package cz.cernilovsky.android.profileapp.activities;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONException;

import cz.cernilovsky.android.profileapp.R;
import cz.cernilovsky.android.profileapp.model.Location;
import cz.cernilovsky.android.profileapp.model.Profile;
import cz.cernilovsky.android.profileapp.services.AddGeofence;
import cz.cernilovsky.android.profileapp.services.NotificationService;
import cz.cernilovsky.android.profileapp.services.ToastService;
import cz.cernilovsky.android.profileapp.storage.LocationsStorage;
import cz.cernilovsky.android.profileapp.storage.ProfilesStorage;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class AddLocationActivity extends Activity {
	private Profile[] profiles;
	private boolean[] onEntryProfiles;
	private boolean[] onLeaveProfiles;
	private double latitude;
	private double longitude;
	private static final String ON_ENTRY = "on_entry";
	private static final String ON_LEAVE = "on_leave";
	private static final String PROFILES = "profiles";
	public static final int GET_POSITION = 1;
	public static final String LOCATIONS = "locations";
	private static final String TAG = "AddLocationActivity";
	private static final int NEW_PROFILE = 2;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_add_location);
		if(savedInstanceState != null) {
			//Log.d(TAG, "savedInstance not null");
			onEntryProfiles = (boolean[]) savedInstanceState.getSerializable(ON_ENTRY);
			onLeaveProfiles = (boolean[]) savedInstanceState.getSerializable(ON_LEAVE);
			profiles = (Profile[]) savedInstanceState.getSerializable(PROFILES);
			loadProfiles();
			latitude = savedInstanceState.getDouble(MapActivity.LATITUDE);
			longitude = savedInstanceState.getDouble(MapActivity.LONGITUDE);
			loadLatLong();
		} else {
			try {
				profiles = ProfilesStorage.loadProfiles(this);
			} catch (IOException e) {
				ToastService.toastSettingsIOError(this);
				e.printStackTrace();
			} catch (JSONException e) {
				ToastService.toastSettingsJSONError(this);
				e.printStackTrace();
			}
			Bundle extras = getIntent().getExtras();
			if(extras != null) {
				setTitle(R.string.edit_location);
				Location l = (Location) extras.getSerializable(LOCATIONS);
				if(l == null)
					return;
				((EditText) findViewById(R.id.editTextLocationName)).setText(l.getName());
				if(l.getOnEntryProfiles() != null) {
					((TextView) findViewById(R.id.textViewOnEntryProfiles)).setText(TextUtils.join(", ", l.getOnEntryProfiles()));
					onEntryProfiles = convertToBoolean(l.getOnEntryProfiles());
				}
				if(l.getOnLeaveProfiles() != null) {
					((TextView) findViewById(R.id.textViewOnLeaveProfiles)).setText(TextUtils.join(", ", l.getOnLeaveProfiles()));
					onLeaveProfiles = convertToBoolean(l.getOnLeaveProfiles());
				}
				latitude = l.getLatitude();
				longitude = l.getLongitude();
				loadLatLong();
				((EditText) findViewById(R.id.editTextRadius)).setText(String.valueOf(l.getRadius()));
			}
		}
	}
	
	private boolean[] convertToBoolean(Profile[] profiles) {
		if(profiles == null)
			return null;
		Profile[] allProfiles = this.profiles;
		if(allProfiles == null) {
			return null;
		}
		boolean[] checked = new boolean[allProfiles.length];
		outer:
		for(int i = 0; i < allProfiles.length; i++) {
			Profile p = allProfiles[i];
			for(Profile p1 : profiles) {
				if(p.equals(p1)) {
					checked[i] = true;
					continue outer;
				}
			}
			checked[i] = false;
		}
			return checked;
	}

	private void loadLatLong() {
		TextView tv = (TextView) findViewById(R.id.textViewLocation);
		tv.setText(getString(R.string.latitude) + ": " + String.format("%1$.2f", latitude) + "\n"
				+ getString(R.string.longitude) + ": " + String.format("%1$.2f", longitude));
	}

	private void loadProfiles() {
			TextView tv = (TextView) findViewById(R.id.textViewOnEntryProfiles);
			boolean[] profiles = onEntryProfiles;
			for(int j = 0; j < 2; j++) {
				if(profiles != null && profiles.length > 0) {
					if(this.profiles == null) {
						return;
					}
					StringBuilder sb = new StringBuilder();
					boolean first = true;
					for(int i = 0; i < profiles.length; i++) {
						boolean checked = profiles[i];
						if(checked) {
							if(first) {
								first = false;
							} else {
								sb.append(", ");
							}
							sb.append(this.profiles[i].getName());
						}
					}
					tv.setText(sb.toString());
				}
				tv = (TextView) findViewById(R.id.textViewOnLeaveProfiles);
				profiles = onLeaveProfiles;
			}
		
	}

	public void save(View view) {
		save(false);
	}
	
	private void save(boolean skipCheckingSizeOfRadius) {
		EditText et = (EditText) findViewById(R.id.editTextLocationName);
		String name = et.getText().toString().trim();
		if(name.equals("")) {
			Toast.makeText(this, R.string.empty_name, Toast.LENGTH_SHORT).show();
			return;
		}
		List<Profile> onEntryProfilesL = new ArrayList<Profile>();
		List<Profile> onLeaveProfilesL = new ArrayList<Profile>();
		for(int i = 0; i < profiles.length; i++) {
			if(onEntryProfiles != null) {
				if(onEntryProfiles[i]) {
					onEntryProfilesL.add(profiles[i]);
				}
			}
			if(onLeaveProfiles != null) {
				if(onLeaveProfiles[i]) {
					onLeaveProfilesL.add(profiles[i]);
				}
			}
		}
		if(onEntryProfilesL.size() == 0 && onLeaveProfilesL.size() == 0) {
			Toast.makeText(this, R.string.at_least_one_profile, Toast.LENGTH_SHORT).show();
			return;
		}
		et = (EditText) findViewById(R.id.editTextRadius);
		String radiusS = et.getText().toString().trim();
		if(radiusS.equals("")) {
			Toast.makeText(this, R.string.radius_empty, Toast.LENGTH_SHORT).show();
			return;
		}
		int radius = Integer.parseInt(radiusS);
		if(!skipCheckingSizeOfRadius) {
			if(radius < 1000) {
				Builder builder = new Builder(this);
				builder.setTitle(R.string.small_radius);
				builder.setMessage(R.string.small_radius_message);
				builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {
						save(true);
						dialog.dismiss();
					}
				});
				builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				});
				builder.setCancelable(true);
				builder.create().show();
				return;
			}
		}
		
		try {
			Bundle extras = getIntent().getExtras();
			if(extras == null) {
				Location location = new Location(name, onEntryProfilesL.toArray(), onLeaveProfilesL.toArray(), latitude, longitude, radius);
				LocationsStorage.addLocation(location, this);
			} else {
				Location location = (Location) extras.getSerializable(LOCATIONS);
				location.setName(name);
				location.setOnEntryProfiles(onEntryProfilesL.toArray());
				location.setOnLeaveProfiles(onLeaveProfilesL.toArray());
				location.setLatitude(latitude);
				location.setLongitude(longitude);
				location.setRadius(radius);
				LocationsStorage.editLocation(location, this);
			}
		} catch (IOException e) {
			ToastService.toastSettingsIOError(this);
			e.printStackTrace();
		} catch (JSONException e) {
			ToastService.toastSettingsJSONError(this);
			e.printStackTrace();
		} 
		finish();
	}
	
	public void setOnLeaveProfiles(View view) {
		setProfiles(ON_LEAVE);
	}
	
	public void setOnEntryProfiles(View view) {
		setProfiles(ON_ENTRY);
	}
	
	public void setLocation(View view) {
		Intent i = new Intent(this, MapActivity.class);
		i.putExtra(MapActivity.LATITUDE, latitude);
		i.putExtra(MapActivity.LONGITUDE, longitude);
		startActivityForResult(i, GET_POSITION);
	}
	
	public void setProfiles(String which) {
				if(profiles == null) {
						Builder builder = new Builder(this);
						builder.setTitle(R.string.no_profiles_title);
						builder.setMessage(R.string.no_profiles_message);
						builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
							
							@Override
							public void onClick(DialogInterface dialog, int which) {
								Intent i = new Intent(AddLocationActivity.this, AddProfileActivity.class);
								startActivityForResult(i, NEW_PROFILE);
								dialog.dismiss();
							}
						});
						builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
							
							@Override
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
							}
						});
						builder.create().show();
						return;
						//profiles = new Profile[0];
				}
				final boolean[] checked;
				if(which.equals(ON_ENTRY)) {
					if(onEntryProfiles == null) {
						onEntryProfiles = new boolean[profiles.length];
					}
					checked = onEntryProfiles;
				} else {
					if(onLeaveProfiles == null) {
						onLeaveProfiles = new boolean[profiles.length];
					}
					checked = onLeaveProfiles;
				}
				String[] listOfProfilesNames = new String[profiles.length];
				for(int i = 0; i < profiles.length; i++) {
					listOfProfilesNames[i] = profiles[i].getName();
				}
				AlertDialog.Builder builder = new AlertDialog.Builder(this);
				builder.setTitle(getString(which.equals(ON_ENTRY) ? R.string.select_on_entry_profiles : R.string.select_on_leave_profiles));
				builder.setMultiChoiceItems(listOfProfilesNames, checked, new DialogInterface.OnMultiChoiceClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which, boolean isChecked) {
						checked[which] = isChecked;
					}
				});
				builder.setCancelable(true);
				builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
						loadProfiles();
					}
				});
				builder.setNeutralButton(R.string.create_new_profile, new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {
						Intent i = new Intent(AddLocationActivity.this, AddProfileActivity.class);
						startActivityForResult(i, NEW_PROFILE);
						dialog.dismiss();
					}
				});
				builder.create().show();
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putSerializable(ON_LEAVE, onLeaveProfiles);
		outState.putSerializable(ON_ENTRY, onEntryProfiles);
		outState.putDouble(MapActivity.LATITUDE, latitude);
		outState.putDouble(MapActivity.LONGITUDE, longitude);
		outState.putSerializable(PROFILES, profiles);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if(requestCode == GET_POSITION) {
			if(resultCode == MapActivity.OK) {
				latitude = data.getDoubleExtra(MapActivity.LATITUDE, 0);
				longitude = data.getDoubleExtra(MapActivity.LONGITUDE, 0);
				loadLatLong();
			}
		} else if(requestCode == NEW_PROFILE) {
			try {
				profiles = ProfilesStorage.loadProfiles(this);
				for(int i = 0; i < 2; i++) {
					boolean[] checked = i == 0 ? onEntryProfiles : onLeaveProfiles;
					if(checked != null && profiles.length != checked.length) {
						boolean[] newChecked = new boolean[profiles.length];
						for(int j = 0; j < checked.length; j++) {
							newChecked[j] = checked[j];
						}
						newChecked[profiles.length-1] = false;
						if(i == 0) {
							onEntryProfiles = newChecked;
						} else {
							onLeaveProfiles = newChecked;
						}
					}
					
				}
				if(onLeaveProfiles != null && profiles.length != onLeaveProfiles.length) {
					boolean[] newOnLeaveProfiles = new boolean[profiles.length];
					for(int i = 0; i < onLeaveProfiles.length; i++) {
						newOnLeaveProfiles[i] = onLeaveProfiles[i];
					}
					newOnLeaveProfiles[profiles.length-1] = false;
					onLeaveProfiles = newOnLeaveProfiles;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}
